import { createCustomError } from "./error";
import message from "./message";
import { wait } from "./timer";

export type IRequestConfig = {
    /** 请求地址 */
    url: string;
    header?: object;
    method?: 'GET' | 'POST' | 'OPTIONS' | 'PUT' | 'HEAD' | 'DELETE' | 'PATCH';
    data?: object | ArrayBuffer;
};

export type IRequestOptions = {
    /** 自定义请求头 */
    header?: object;
    /** 是否缓存 */
    cache?: boolean | number;
    /** 是否使用Mock */
    mock?: boolean;
    /** 是否安静 */
    quiet?: boolean;
    /** 是否加密 */
    encrypt?: boolean;
};

type IResponseData<T = any> = T & {
    status: number,
    info: string,
    data: T,
    sid?: string
};


function _request<T = any>(config: IRequestConfig, options?: IRequestOptions) {
    return new Promise<T>((resolve, reject) => {
        const cancel = wait(600, () => message.loading('请求中'));

        tt.request({
            ...config,
            success: res => {
                message.hideLoading();

                if (res.statusCode !== 200) {
                    const errMsg =
                        typeof res?.data === 'string' ? res.data || res.errMsg : res.errMsg;

                    switch (res.statusCode) {
                        case 401:
                        // 未授权
                        // goLogin();
                        case 491:
                        // 未注册
                        default:
                            !options?.quiet && message.error(errMsg, 1500);
                            break;
                    }

                    return reject(
                        createCustomError(errMsg, {
                            config,
                            response: res,
                        }),
                    );
                }
                const data = res?.data as IResponseData<T>;
                const { data: _data, ...rest } = data ?? {};

                if (_data) {
                    resolve({ ...rest, ..._data });
                } else if (data?.data === null) {
                    resolve(undefined)
                } else {
                    resolve(data);
                }
            },
            fail: ({ errMsg }) => {
                message.hideLoading();

                !options?.quiet && message.error(errMsg, 1500);

                reject(createCustomError(errMsg));
            },
            complete: () => {
                cancel();
            },
        });
    });
}

/** 原子请求 */
export async function request<T = any>(
    config: IRequestConfig,
    options?: IRequestOptions,
) {

    return _request<T>({
        ...config,
        header: {
            ...config.header,
            ...options?.header,
        },
    } as IRequestConfig)
}
